﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace MvcFlow.DefinitionProviders
{
    public class FileWorkflowDefinitionProvider : IWorkflowDefinitionProvider
    {
        private readonly IEnumerable<string> searchPaths;

        public event System.Action<IWorkflowDefinitionProvider> Changed;

        public async Task<string> GetWorkflowDefinition(System.Web.Routing.RequestContext requestContext, string workflowName)
        {
            foreach (var searchPath in searchPaths)
            {
                var fullPath = requestContext.HttpContext.Server.MapPath("~" + (searchPath.StartsWith("/") ? string.Empty : "/") + searchPath);
                var fullFilename = Path.Combine(fullPath, workflowName + ".xaml");

                if (File.Exists(fullFilename))
                {
                    try
                    {
                        using (var stream = File.OpenRead(fullFilename))
                        {
                            return await new StreamReader(stream).ReadToEndAsync();
                        }
                    }
                    catch (FileNotFoundException)
                    {
                        // Just try the next search path in case of a race condition
                        // between File.Exits and File.Open
                    }
                }
            }

            return null;
        }

        public FileWorkflowDefinitionProvider(IEnumerable<string> searchPaths = null)
        {
            if (searchPaths == null || !searchPaths.Any())
            {
                this.searchPaths = new[] { "Workflows" };
            }
            else
            {
                this.searchPaths = searchPaths;
            }
        }
    }
}